from django.views.generic import ListView, CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from core.models import ClassEvaluation
from core.forms import ClassEvaluationForm
from core.utils import log_operation

class ClassEvaluationListView(LoginRequiredMixin, ListView):
    """
    班级评估列表视图
    基于Django的ListView实现，展示符合当前用户权限的班级评估记录
    添加了分页功能以优化大数据量下的性能
    """
    model = ClassEvaluation
    template_name = 'class_evaluation/list.html'
    context_object_name = 'evaluations'
    paginate_by = 20  # 每页显示20条记录

    def get_queryset(self):
        """
        获取查询集，并根据用户角色进行过滤
        使用select_related优化外键关联查询，减少数据库查询次数
        
        Returns:
            QuerySet: 过滤后的班级评估查询集
        """
        # 使用select_related预加载关联对象，避免N+1查询问题
        queryset = super().get_queryset()
        current_role = self.request.session.get('CURRENT_ROLE')
        
        # 班主任可以查看本班所有教师的评估
        if current_role == 'homeroom_teacher':
            queryset = queryset.filter(
                class_schedule__class_info__homeroom_teacher=self.request.user
            )
        # 普通教师只能查看自己授课的评估
        elif current_role == 'teacher':
            queryset = queryset.filter(
                class_schedule__teacher_subject__teacher=self.request.user
            )
        
        return queryset

    def get_context_data(self, **kwargs):
        """
        重写以添加分页上下文
        
        Returns:
            dict: 包含分页信息的上下文字典
        """
        context = super().get_context_data(**kwargs)
        evaluations = self.get_queryset()
        paginator = Paginator(evaluations, self.paginate_by)
        page = self.request.GET.get('page')
        
        try:
            evaluated_page = paginator.page(page)
        except PageNotAnInteger:
            # 如果页码不是整数，返回第一页
            evaluated_page = paginator.page(1)
        except EmptyPage:
            # 如果页码超出范围，返回最后一页
            evaluated_page = paginator.page(paginator.num_pages)
        
        context['evaluations'] = evaluated_page
        return context

class ClassEvaluationCreateView(LoginRequiredMixin, CreateView):
    """
    班级评估创建视图
    基于Django的CreateView实现，用于创建新的班级评估记录
    """
    model = ClassEvaluation
    form_class = ClassEvaluationForm
    template_name = 'class_evaluation/form.html'
    
    def get_success_url(self):
        """
        定义表单提交成功后的重定向URL
        
        Returns:
            str: 重定向到班级评估列表页面的URL
        """
        # 确保class_id有效
        class_id = getattr(getattr(self.object, 'class_schedule', None), 'class_info', None)
        if class_id and hasattr(class_id, 'id'):
            class_id = class_id.id
        else:
            # 默认为1，如果无法获取有效class_id
            class_id = 1
        return reverse('core:class_evaluation_list', kwargs={'class_id': class_id})

    def form_valid(self, form):
        response = super().form_valid(form)
        log_operation(
            user=self.request.user,
            operation_type='create',
            content_type='ClassEvaluation',
            object_id=self.object.id,
            object_name=str(self.object),
            request=self.request,
            details=f'创建班级评估: {self.object.class_schedule}'
        )
        return response

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs

class ClassEvaluationUpdateView(LoginRequiredMixin, UpdateView):
    """
    班级评估更新视图
    基于Django的UpdateView实现，用于更新现有班级评估记录
    """
    model = ClassEvaluation
    form_class = ClassEvaluationForm
    template_name = 'class_evaluation/form.html'
    
    def form_valid(self, form):
        """
        表单验证通过后的处理
        记录操作日志并返回响应
        
        Args:
            form: 验证通过的表单
            
        Returns:
            HttpResponse: 重定向响应
        """
        response = super().form_valid(form)
        log_operation(
            user=self.request.user,
            operation_type='update',
            content_type='ClassEvaluation',
            object_id=self.object.id,
            object_name=str(self.object),
            request=self.request,
            details=f'更新班级评估: {self.object.class_schedule}'
        )
        return response
    
    def get_success_url(self):
        """
        定义表单提交成功后的重定向URL
        
        Returns:
            str: 重定向到班级评估列表页面的URL
        """
        # 确保class_id有效
        class_id = getattr(getattr(self.object, 'class_schedule', None), 'class_info', None)
        if class_id and hasattr(class_id, 'id'):
            class_id = class_id.id
        else:
            # 默认为1，如果无法获取有效class_id
            class_id = 1
        return reverse('core:class_evaluation_list', kwargs={'class_id': class_id})

class ClassEvaluationDeleteView(LoginRequiredMixin, DeleteView):
    """
    班级评估删除视图
    基于Django的DeleteView实现，用于删除班级评估记录
    """
    model = ClassEvaluation
    template_name = 'class_evaluation/confirm_delete.html'
    
    def delete(self, request, *args, **kwargs):
        """
        执行删除操作
        记录操作日志并返回响应
        
        Args:
            request: HTTP请求对象
            args: 位置参数
            kwargs: 关键字参数
            
        Returns:
            HttpResponse: 重定向响应
        """
        evaluation = self.get_object()
        log_operation(
            user=request.user,
            operation_type='delete',
            content_type='ClassEvaluation',
            object_id=evaluation.id,
            object_name=str(evaluation),
            request=request,
            details=f'删除班级评估: {evaluation.class_schedule}'
        )
        return super().delete(request, *args, **kwargs)
    
    def get_success_url(self):
        """
        定义删除成功后的重定向URL
        
        Returns:
            str: 重定向到班级评估列表页面的URL
        """
        # 确保class_id有效
        class_id = getattr(getattr(self.object, 'class_schedule', None), 'class_info', None)
        if class_id and hasattr(class_id, 'id'):
            class_id = class_id.id
        else:
            # 默认为1，如果无法获取有效class_id
            class_id = 1
        return reverse('core:class_evaluation_list', kwargs={'class_id': class_id})